﻿/**
* @description  Class handles loading and playback of SWFs.
*/
package com.foed.media.controllers {

	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.errors.IOError;

	import com.foed.events.MediaEvent;

	public class SWFController extends MediaController {
			
		private var _SWFLoader_ld:Loader;
		private var _SWFHolder_sp:Sprite;

		/**
		* @description  Called when the media loads fully into the player and scripts can be accessed.
		*
		* @param  pEvent  Event fired by LoaderInfo.
		*/
		private function onLoadInit(pEvent:Event):void {
			mediaDuration = getContent().totalFrames;
			startMedia();
			_SWFHolder_sp.visible = true;
			dispatchEvent(new MediaEvent(MediaEvent.METADATA, mediaPosition, mediaDuration, _SWFHolder_sp.width, _SWFHolder_sp.height));
			dispatchEvent(pEvent);
		}
	
		/**
		* @description  Called when the media loads fully into the player.
		*
		* @param  pEvent  Event fired by LoaderInfo.
		*/
		private function onLoadComplete(pEvent:Event):void {
			dispatchEvent(pEvent);
		}
	
		/**
		* @description  Called when there is an error loading media.
		*
		* @param  pEvent  Event fired by LoaderInfo.
		*/
		private function onLoadError(pEvent:Event):void {
			dispatchEvent(pEvent);
		}
	
		/**
		* @description  Called when the request for the media file is made.
		*
		* @param  pEvent  Event fired by LoaderInfo.
		*/
		private function onLoadStart(pEvent:Event):void {
			dispatchEvent(pEvent);
		}
	
		/**
		* @description  Called repeatedly as the media is loading into the player.
		*
		* @param  pEvent  Event fired by LoaderInfo.
		*/
		private function onLoadProgress(pEvent:Event):void {
			dispatchEvent(pEvent);
		}
		
		/**
		* @description  Returns the movie clip of loaded content.
		*
		* @returns  The LoaderInfo content cast as a movie clip.
		*/
		private function getContent():MovieClip {
			return _SWFLoader_ld.content as MovieClip;
		}
	
		/**
		* @description  Applies current sound settings to media.
		*/		
		override protected function applySoundTransform():void {
			_SWFHolder_sp.soundTransform = getSoundTransform();
		}

		/**
		* @description  Called on an enter frame as the media is played back.
		*
		* @param  pEvent  The event fired by the Sprite.
		*/		
		override protected function trackProgress(pEvent:Event):void {
			if (mediaPosition == mediaDuration) {
				stopMedia();
				getContent().gotoAndStop(mediaDuration);
				dispatchEvent(new MediaEvent(MediaEvent.COMPLETE, mediaPosition, mediaDuration));
			}
			super.trackProgress(pEvent);
		}
	
		/**
		* @description  Adds or removes the enter frame handler that monitors media playback.
		*
		* @param  pStart  True to start monitoring. False otherwise.
		*/		
		override protected function startTrackProgress(pStart:Boolean):void {
			if (pStart) {
				dispatchEvent(new MediaEvent(MediaEvent.START, mediaPosition, mediaDuration));
				_SWFHolder_sp.addEventListener(Event.ENTER_FRAME, trackProgress, false, 0, true);
			} else {
				dispatchEvent(new MediaEvent(MediaEvent.STOP, mediaPosition, mediaDuration));
				_SWFHolder_sp.removeEventListener(Event.ENTER_FRAME, trackProgress);
			}
		}
	
		/**
		* @description  Triggers the request and loading of the controller's media.
		*
		* @param  pFileURL  The http or rtmp path to the file to load.
		*/		
		override public function loadMedia(pFileURL:String):void {
			super.loadMedia(pFileURL);
			_SWFHolder_sp = new Sprite();
			_SWFLoader_ld = new Loader();
			var pLoaderInfo:LoaderInfo = _SWFLoader_ld.contentLoaderInfo;
			pLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete, false, 0, true);
			pLoaderInfo.addEventListener(Event.INIT, onLoadInit, false, 0, true);
			pLoaderInfo.addEventListener(Event.OPEN, onLoadStart, false, 0, true);
			pLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError, false, 0, true);
			pLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress, false, 0, true);
			_SWFHolder_sp.addChild(_SWFLoader_ld);
			applySoundTransform();
			_SWFHolder_sp.visible = false;
			try {
				_SWFLoader_ld.load(new URLRequest(mediaFile));
				dispatchEvent(new MediaEvent(MediaEvent.LOAD));
			} catch (e:Error) {}
		}
	
		/**
		* @description  Begins playback of the loaded media.
		*/		
		override public function startMedia():void {
			super.startMedia();
			getContent().play();
		} 
	
		/**
		* @description  Sends the media to the specified position, in milliseconds.
		*
		* @param  pOffset  The position in milliseconds to send the media to.
		*/
		override public function seek(pOffset:Number):void {
			pOffset = Math.round(pOffset);
			if (playing) {
				getContent().gotoAndPlay(pOffset-1);
			} else {
				getContent().gotoAndStop(pOffset);
			}
			super.seek(pOffset);
		} 
	
		/**
		* @description  Halts playback of media.
		*/		
		override public function stopMedia():void {
			getContent().gotoAndStop(1);
			super.stopMedia();
		} 
	
		/**
		* @description  Pauses or resumes playback of media.
		*
		* @param  pPause  True to pause media. False to resume.
		*/		
		override public function pauseMedia(pPause:Boolean):void {
			super.pauseMedia(pPause);
			if (paused) {
				super.stopMedia();
				getContent().stop();
			} else {
				startMedia();
			}
			startTrackProgress(!paused);
		} 

		/**
		* @description  Returns the current frame of the media.
		*
		* @returns  The current frame of the media.
		*/		
		override public function get mediaPosition():Number {
			return getContent().currentFrame;
		}
	
		/**
		* @description  Returns the media playback object for the controller.
		*
		* @returns  A reference to the object containing the media.
		*/		
		override public function get media():Object { return _SWFHolder_sp; }

	}
	
}